using System;
using PingPong.Generic;
using PingPong.Generic.Helpers;

namespace PingPong.GameEngine
{

	public class GameAction
	{
		#region Members

		/// <summary>
		/// The type of the game action.
		/// </summary>
		private Lazy<GameActionType> gameActionType;
		/// <summary>
		/// The scalar.
		/// </summary>
		private Lazy<string> scalarExpression;

		#endregion

		#region Properties

		/// <summary>
		/// Gets the type of the game action.
		/// </summary>
		/// <value>The type of the game action.</value>
		public GameActionType GameActionType
		{
			get
			{
				return this.gameActionType.Value;
			}
		}

		/// <summary>
		/// Gets the scalar.
		/// </summary>
		/// <value>The scalar.</value>
		public int Scalar
		{
			get
			{
				Engine.ExpressionParser.Interpret(this.scalarExpression.Value);
				return Engine.ExpressionParser.Int;
			}
		}

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="PingPong.GameEngine.GameAction"/> class.
		/// </summary>
		public GameAction()
		{
			this.gameActionType = new Lazy<GameActionType>(() => GameActionType.None);
			this.scalarExpression = new Lazy<string>(() => string.Empty);
		}

		#endregion

		#region Methods

		#region Events

		/// <summary>
		/// Fires the on game action activated.
		/// </summary>
		/// <returns>The on game action activated.</returns>
		private GameAction FireOnGameActionActivated()
		{
			EventHelper.SafeFireEvent(OnGameActionActivated,this,new DataEventArgs<int>(this.Scalar));
			return this;
		}

		#endregion

		/// <summary>
		/// Sets the type of the game action.
		/// </summary>
		/// <returns>The game action.</returns>
		/// <param name="gameActionType">Game action type.</param>
		public GameAction SetGameActionType(GameActionType gameActionType)
		{
			this.gameActionType = new Lazy<GameActionType>(() => gameActionType);
			return this;
		}

		/// <summary>
		/// Sets the scalar expression.
		/// </summary>
		/// <returns>The game action.</returns>
		/// <param name="expression">Expression.</param>
		public GameAction SetScalarExpression(string expression)
		{
			this.scalarExpression = new Lazy<string>(() => expression);
			return this;
		}

		/// <summary>
		/// Execute this instance.
		/// </summary>
		public GameAction Execute()
		{
			return FireOnGameActionActivated();
		}

		#endregion

		#region Events

		/// <summary>
		/// Occurs when on game action activated.
		/// </summary>
		public event EventHandler<DataEventArgs<int>> OnGameActionActivated;

		#endregion
	}
}

